<template>
  <el-popover
    v-model="visible"
    :disabled="disabled"
    placement="bottom-start"
    trigger="manual"
    @show="onShow"
  >
    <el-alert
      slot="reference"
      ref="alert"
      type="info"
      :closable="false"
      :class="{'is-disabled': disabled}"
      :style="{width: $attrs.width, minWidth: '310px'}"
      @mouseenter.native="onAlertMouseEnter"
      @mouseleave.native="onAlertMouseLeave"
    >
      <div slot="title" style="width:100%;line-height: 34px;">
        {{`共 ${totalCount} 个组织节点，已选中 ${$refs.tree ? $refs.tree.getCheckedKeys().length : 0} 个`}}
        <div v-show="$refs.tree && $refs.tree.getCheckedKeys().length" style="float:right;">
          <el-button type="text" style="padding: 0px;margin-left: 8px" @click="onResetClick">重置</el-button>
        </div>
      </div>
    </el-alert>
    <div
      @mouseenter="onPopoverContentMouseEnter"
      @mouseleave="onPopoverContentMouseLeave"
    >
      <el-input
        ref="searchInput"
        v-model.trim="filterText"
        placeholder="输入名称以搜索"
        prefix-icon="el-icon-search"
        clearable
      />
      <el-tree
        ref="tree"
        v-loading="loading"
        :data="orgs"
        show-checkbox
        :check-strictly="$attrs['check-strictly'] == undefined ? true : $attrs['check-strictly']"
        :props="{
          children: 'children',
          label: 'name'
        }"
        node-key="id"
        :default-expanded-keys="defaultExpandedKeys"
        :filter-node-method="filterOrg"
        style="overflow: auto;"
        :style="{maxHeight: '300px', minWidth}"
        v-bind="$attrs"
        @check="onCheck"
      />
    </div>
  </el-popover>
</template>


<script>
export default {
  inheritAttrs: false,
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    value: null,
    disabled: {
      type: Boolean,
      default: false
    },
    defaultVisible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      filterText: '',
      loading: true,
      orgs: [],
      defaultExpandedKeys: this.$attrs['default-expanded-keys'] || [1, 215, 216, 217],
      selectedOrgName: null,

      visible: false,
      popoverContentHovered: false,
      minWidth: '380px'
    };
  },
  watch: {
    disabled(val) {
      if (val) {
        this.visible = true;
        this.clear();
      }
    }
  },
  computed: {
    totalCount() {
      return count(this.orgs);
      function count(nodes) {
        let n = nodes.length;
        nodes.forEach(node => {
          if (node.children)
            n += count(node.children);
        });
        return n;
      }
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    },
    value(val) {
      this.setValue(val);
    }
  },
  async mounted() {
    const orgs = await this.$http.get('/api/org/listOrg');
    this.orgs = orgs;
    this.$nextTick(() => {
      // 异步加载数据之前value已经从父组件传递给本组件但tree未更新，此处必须手动设置
      this.setValue(this.value);
    });
    this.loading = false;
    setTimeout(() => {
      this.visible = this.defaultVisible;
    }, 200);
  },
  methods: {
    onCheck(node, checkeds) {
      this.$emit('change', checkeds.checkedKeys);
    },
    onShow() {
      this.minWidth = (this.$refs.alert.$el.offsetWidth - 26) + 'px';
    },
    onAlertMouseEnter() {
      this.visible = true;
      clearInterval(this.visibleTimer);
    },
    onAlertMouseLeave() {
      if (!this.popoverContentHovered) {
        this.close();
      }
    },
    onPopoverContentMouseEnter() {
      this.popoverContentHovered = true;
      clearInterval(this.visibleTimer);
    },
    onPopoverContentMouseLeave() {
      this.popoverContentHovered = false;
      this.close();
    },
    onResetClick() {
      this.clear();
    },
    filterOrg(value, orgs) {
      if (!value) return true;
      return orgs.name.indexOf(value) !== -1;
    },
    setValue(orgIds) {
      if (orgIds == null || orgIds == '') {
        this.filterText = '';
        this.selectedOrgName = null;
        if (this.$refs.tree)
          this.$refs.tree.setCheckedKeys([]);
      } else {
        if (typeof orgIds == 'string')
          orgIds = orgIds.split(',').map(Number);
        this.$refs.tree.setCheckedKeys(orgIds);
      }
    },
    show(delay) {
      setTimeout(() => {
        this.visible = true;
      }, delay);
    },
    close() {
      this.visibleTimer = setTimeout(() => {
        this.visible = false;
      }, 200);
    },
    clear() {
      this.filterText = '';
      this.selectedOrgName = null;
      this.defaultExpandedKeys = [];
      this.$nextTick(() => {
        this.$refs.tree.setCheckedKeys([]);
      });
      this.$emit('change', []);
    }
  }
}
</script>

<style scoped>
.el-alert {
  height: 34px;
  user-select: none;
  cursor: pointer;
}

.el-alert.is-disabled {
  cursor: not-allowed;
}

.el-alert >>> .el-alert__content {
  width: 100%;
}
</style>